<template>
	<view>
		<view class="watermark" v-if="isAPP">
			<view v-for="item in watermark" :style="`color:${item.font_color};font-size:${item.font_size}rpx;`">{{item.text}}</view>
		</view>
		<view class="canvasBox" v-show='isUse'>
			<view class="trachBox" :style="{backgroundColor: !trackStatus ?'aliceblue' : 'khaki'}" @click='handlerTrach'
				v-if='isUseTorch'>
				<img src="./track.svg" class='trach'>
			</view>
			<view class="shutterBox" @click='hanlderShutter' hover-class="avtive">
				<view class="shutter"></view>
			</view>
		</view>
		<view class="error" v-show='!isUse'>
			<view class="on1">相机权限被拒绝，请尝试如下操作：</view>
			<view>· 刷新页面后重试；</view>
			<view>· 在系统中检测当前App或浏览器的相机权限是否被禁用；</view>
			<view>· 如果依然不能体验，建议在微信中打开链接；</view>

		</view>
	</view>
</template>
<script>
	import {
		imageCompres
	} from '@/utils/utils.js';
	export default {
		props: {
			exact: {
				type: String,
				default: 'user' // environment 后摄像头  user 前摄像头
			},
			//水印
			watermark: {
				type: Array,
				default: () => []
			}
		},
		data() {
			return {
				isAPP:false,
				isUse: false,

				windowWidth: 0,
				windowHeight: 0,
				video: null,
				canvas: null,
				canvas2d: null,
				cameraCanvas: null,
				cameraCanvas2d: null,



				// 闪光灯
				track: null,
				isUseTorch: false,
				trackStatus: false
			}
		},
		mounted() {
			let that = this;
			console.log(document)
			if (process.env.UNI_PLATFORM === 'h5') {
				if (origin.indexOf('https') === -1) throw '请在 https 环境中使用本插件。'

				this.windowWidth = document.documentElement.clientWidth || document.body.clientWidth
				this.windowHeight = document.documentElement.clientHeight || document.body.clientHeight
				this.$nextTick(() => {
					this.video = document.createElement('video')
					this.video.width = this.windowWidth
					this.video.height = this.windowHeight
					const canvas = document.createElement('canvas')
					this.canvas = canvas
					canvas.id = 'canvas'
					canvas.width = this.windowWidth
					canvas.height = this.windowHeight
					canvas.style = 'position: fixed;top: 0;left: 0;z-index:10;'
					this.canvas2d = canvas.getContext('2d')

					// 设置当前宽高 满屏
					const canvasBox = document.querySelector('.canvasBox')
					canvasBox.append(this.video)
					canvasBox.append(canvas)
					canvasBox.style = `transform:scaleX(-1);width:${this.windowWidth}px;height:${this.windowHeight}px;`

					const cameraCanvas = document.createElement('canvas')
					this.cameraCanvas = cameraCanvas
					cameraCanvas.id = 'cameraCanvas'
					cameraCanvas.width = this.windowWidth
					cameraCanvas.height = this.windowHeight
					cameraCanvas.style = 'display:none;'
					canvasBox.append(canvas)
					this.cameraCanvas2d = cameraCanvas.getContext('2d')

					this.openScan()
				})
			}else{
				// ✅ App端
				that.isAPP = true;
				uni.chooseImage({
				  count: 1, // 拍1张
				  sourceType: ['camera'], // 只调用摄像头
				  success: async function (res) {
				    // const baseResult = await imageCompres(res.tempFilePaths[0])
					that.$emit('success', res.tempFilePaths[0])
				  },
				  fail: function (err) {
				    console.error('调用摄像头失败', err);
				  }
				});
			}
		},
		methods: {
			openScan() {
				let width = this.transtion(this.windowHeight)
				let height = this.transtion(this.windowWidth)

				const videoParam = {
					audio: false,
					video: {
						facingMode: {
							exact: this.exact
						},
						width,
						height
					}
				}


				navigator.mediaDevices.getUserMedia(videoParam).then((stream) => {
					this.isUse = true
					this.video.srcObject = stream
					this.video.setAttribute('playsinline', true)
					this.video.setAttribute('webkit-playsinline', true)
					this.video.play()
					this.makeWatermark(this.canvas2d)

					this.track = stream.getVideoTracks()[0];
					setTimeout(() => {
						this.isUseTorch = this.track.getCapabilities().torch || null
					}, 500)
				}).catch((err) => {
					console.log('设备不支持', err);
					this.isUse = false
				})
			},

			async makeWatermark(ctx2d) {
				if (this.watermark.length === 0) return
				for (let item of this.watermark) {
					switch (item.type) {
						case 'img':
							const [getImgErr, {
								path: imgPath
							}] = await uni.getImageInfo({
								src: item.url
							});
							if (getImgErr) throw item.url + '没有找到'
							const img = await this.getImg(imgPath)
							ctx2d.drawImage(img, item.x, item.y, item.w, item.h)

							break;
						case 'text':
							const color = item.font_color || "#000"
							const fontSize = item.font_size || 16

							ctx2d.fillStyle = color
							ctx2d.font = `${fontSize}px normal`
							ctx2d.fillText(item.text, item.x, item.y)
							break;
					}

				}
			},

			getImg(path) {
				return new Promise((resolve, reject) => {
					return new Promise((resolve, reject) => {
						// H5端使用 Image 构造函数
						if (process.env.UNI_PLATFORM === 'h5') {
							const img = new Image();
							img.src = path;
							img.onload = () => {
								resolve(img);
							};
							img.onerror = (err) => {
								reject(err);
							};
						} else {
							// 非H5端（App、小程序等）使用 uni.getImageInfo
							uni.getImageInfo({
								src: path,
								success: (res) => {
									resolve(res); // res 中包含 width, height, path 等
								},
								fail: (err) => {
									reject(err);
								}
							});
						}
					});
				})
			},


			transtion(number) {
				return number * 2
			},

			// 快门
			async hanlderShutter() {
				this.cameraCanvas2d.scale(-1, 1);
				this.cameraCanvas2d.translate(-this.windowWidth, 0);
				this.cameraCanvas2d.drawImage(this.video, 0, 0, this.windowWidth, this.windowHeight)
				await this.makeWatermark(this.cameraCanvas2d)
				const img = this.cameraCanvas.toDataURL('image/png')
				this.$emit('success', img)
			},

			handlerTrach() {
				console.log(12312)
				this.trackStatus = !this.trackStatus
				this.track.applyConstraints({
					advanced: [{
						torch: this.trackStatus
					}]
				})
			},

			closeCamera() {
				if (this.video.srcObject) {
					this.video.srcObject.getTracks().forEach((track) => {
						track.stop()
					})
				}
			},

		},
		destroyed() {
			this.closeCamera()
		},
	}
</script>
<style lang="scss" scoped>
	page {
		background-color: #333;
	}

	.canvasBox {
		position: relative;

		.shutterBox {
			position: absolute;
			transform: translateX(-50%);
			left: 50%;
			bottom: 100rpx;
			background-color: aliceblue;
			width: 120rpx;
			height: 120rpx;
			border-radius: 100rpx;
			display: flex;
			align-items: center;
			justify-content: center;
			box-shadow: 2rpx 4rpx 8rpx rgba(000, 000, 000, 0.3);
			z-index: 100;
			overflow: hidden;

			.shutter {
				width: 70rpx;
				height: 70rpx;
				border: 10rpx solid #333;
				border-radius: 100rpx;


			}

			&.avtive::after {
				content: '';
				display: block;
				position: absolute;
				top: 0;
				left: 0;
				bottom: 0;
				right: 0;
				background-color: rgba(000, 000, 000, 0.5);
			}
		}

		.trachBox {
			position: absolute;
			transform: translateX(-50%);
			left: 30%;
			bottom: 100rpx;
			width: 60rpx;
			height: 60rpx;
			display: flex;
			align-items: center;
			justify-content: center;
			border-radius: 100rpx;
			box-shadow: 2rpx 4rpx 8rpx rgba(000, 000, 000, 0.3);
			z-index: 30;

			.trach {
				width: 50rpx;
			}
		}

	}

	.error {
		color: #fff;
		padding: 40rpx;
		font-size: 24rpx;

		.on1 {
			font-size: 30rpx;
		}
	}
	.watermark{
		text-align: center;
	}
</style>